// 基于axios封装网络请求
// 每个程序员的想法都不一样，封装的地方和名字都不一样，但思想相同
import theAxios from 'axios'
// import { reject } from 'core-js/fn/promise'
import Notify from '@/utils/Notify'
// 引入路由对象 router
import router from '@/router'
import { getToken, removeToken } from '@/utils/token.js' // , setToken
// import { getNewTokenAPI } from '@/api/index.js'

const axios = theAxios.create({
  baseURL: 'http://geek.itheima.net/',
  timeout: 20000 // 20秒超时时间（请求20s无响应直接判定超时）
})

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  // 目标： 统一携带token
  // 判断本地有token再携带，判断具体api/index.js里如没有携带Authorization,我再添加上去
  // ?.可选链操作符，如果前面对象里没有length,整个表达式原地返回一个undefined
  // console.log(config)
  if (getToken()?.length > 0 && config.headers.Authorization === undefined) {
    config.headers.Authorization = `Bearer ${getToken()}`
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器 响应拦截器一定要放在真正发送axios代码的前面
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  // 如果http响应状态码为2xx,3xx就进入这里
  return response
}, async function (error) {
  // 如果
  // 对响应错误做点什么
  console.dir(error)
  if (error.response.status === 401) {
    // Notify({ type: 'warning', message: '身份已过期' })
    removeToken() // 如果token过期了，要先清除token，才能让路由守卫判断失效，放行我去登录页

    // router.currentRoute 相当于vue文件内的this.$route 是当前路由对象的信息
    // fullPath, 路由对象里完整路由路径#后面的一切
    console.log('楼下是router.currentRoute相当于vue文件内的this.$route 是当前路由对象的信息')
    console.log(router.currentRoute) // router.currentRoute
    // 已经跳转到了登录页面，?path...是保存的跳转之前的路由路径（未遂地址），会保存到登录页面，当在登录页面点击登录的时候，用this.$route.query.path获取到未遂地址,再进行跳转
    router.replace(`/login?path=${router.currentRoute.fullPath}`)

    // 方式1：强制跳转到登录，用户有感知
    // router.replace('/login')

    // 方式2：使用refresh_token换回新的token继续使用，用户没有感知，用户效果好
    // const res = await getNewTokenAPI()
    // console.log(res)
    // // 1.更新token在本地
    // setToken(res.data.data.token)
    // // 2.更新新的token在请求头里
    // error.config.headers.Authorization = `Bearer ${res.data.data.token}`
    // // 3. 未完成这次请求，再发起一次
    // // error.config就是上一次请求的配置对象
    Notify({ type: 'warning', message: '身份认证已过期' })
    // return axios(error.config)
  } else if (error.response.status === 500 && error.config.url === '/v1_0/authorizations' && error.config.method === 'put') {
    // 刷新的refresh_token也过期了
    localStorage.clear() // 清除掉所有token
    Notify({ type: 'warning', message: '身份认证已过期' })
    router.replace('/login')
  }
  return Promise.reject(error)
})

// 专门设置传参传一个对象 如果外面没有给某个参数传值，设置默认值 发送请求的代码
export default ({ url, method = 'GET', params = {}, data = {}, headers = {} }) => {
  return axios({
    url,
    method,
    params,
    data,
    headers
  })
  // 如果将来要更换一个发送ajax请求的方法 如jQuery
  // return new Promise((resolve, reject) => {
  //     // jQuery与axios区别在于，axios有params
  //     // 判断如果params有值，需要自己写js代码，把params对象里的key和value拼接到url上
  // $for.ajax({
  //     url,
  //     data,
  //     headers,
  //     type: method,
  //     success: (res) => {
  //         resolve(res)
  //     },
  //     error: err => {
  //         reject(err)
  //     }
  // })
  // })
}
